#ifndef _CARDTYPE_H_
#define _CARDTYPE_H_

class CardTypeData;
class PokerData;

class CardType {
  public:
    enum Type {
      HighCard,
      OnePair,
      TwoPair,
      ThreeOfAKind,
      Straight,
      Flush,
      FullHouse,
      FourOfAKind,
      StraightFlush,
      RoyalStraightFlush,
    };

    virtual CardTypeData getCardType(const PokerData & data) const = 0;
    virtual const CardType * getNextType() const = 0;
};

class HighCard : public CardType {
  public:
    HighCard();
    virtual ~HighCard();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class OnePair : public CardType {
  public:
    OnePair();
    virtual ~OnePair();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class TwoPair : public CardType {
  public:
    TwoPair();
    virtual ~TwoPair();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class ThreeOfAKind : public CardType {
  public:
    ThreeOfAKind();
    virtual ~ThreeOfAKind();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class Straight : public CardType {
  public:
    Straight();
    virtual ~Straight();  
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class Flush : public CardType {
  public:
    Flush();
    virtual ~Flush();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class FullHouse : public CardType {
  public:
    FullHouse();
    virtual ~FullHouse();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class FourOfAKind : public CardType {
  public:
    FourOfAKind();
    virtual ~FourOfAKind();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class StraightFlush : public CardType {
  public:
    StraightFlush();
    virtual ~StraightFlush();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

class RoyalStraightFlush : public CardType {
  public:
    RoyalStraightFlush();
    virtual ~RoyalStraightFlush();
    virtual CardTypeData getCardType(const PokerData & data) const;
    virtual const CardType * getNextType() const;
};

#endif
